﻿using System;
using System.Xml.Serialization;

namespace WhiteFlow.DevTrackingTool.UI.Models
{
    /// <summary>
    /// Contains informations about an expense entry of an expense report.
    /// </summary>
    [Serializable]
    public class Expense : WorksheetItem
    {
        #region Constants

        /// <summary>
        /// The ExpenseType property name.
        /// </summary>
        public const string ExpenseTypePropertyName = "ExpenseType";

        /// <summary>
        /// The Description property name.
        /// </summary>
        public const string DescriptionPropertyName = "Description";

        /// <summary>
        /// The Kilometers property name.
        /// </summary>
        public const string KilometersPropertyName = "Kilometers";

        /// <summary>
        /// The IsAmountCalculated property name.
        /// </summary>
        public const string IsAmountCalculatedPropertyName = "IsAmountCalculated";

        /// <summary>
        /// The Amount property name.
        /// </summary>
        public const string AmountPropertyName = "Amount";

        /// <summary>
        /// The Attachments property name.
        /// </summary>
        public const string AttachmentsPropertyName = "Attachments";

        #endregion

        #region Fields

        private ExpenseReport owner;

        private ExpenseType expenseType;
        
        private string description;
        
        private int kilometers;

        private bool isAmountCalculated;

        private decimal amount;
        
        private int attachments;
        
        #endregion

        #region Properties

        [XmlAttribute(AttributeName = ExpenseTypePropertyName)]
        public ExpenseType ExpenseType
        {
            get { return expenseType; }
            set
            {
                expenseType = value;
                OnPropertyChanged(ExpenseTypePropertyName);

                OnWorksheetItemChanged();

                UpdateCalculatedAmount();

                if (value == Models.ExpenseType.Fuel)
                {
                    IsAmountCalculated = true;
                }
                else
                {
                    IsAmountCalculated = false;
                }
            }
        }

        [XmlAttribute(AttributeName = DescriptionPropertyName)]
        public string Description
        {
            get { return description; }
            set
            {
                description = value;
                OnPropertyChanged(DescriptionPropertyName);
                
                OnWorksheetItemChanged();
            }
        }

        [XmlAttribute(AttributeName = KilometersPropertyName)]
        public int Kilometers
        {
            get { return kilometers; }
            set
            {
                kilometers = value;
                OnPropertyChanged(KilometersPropertyName);
                
                OnWorksheetItemChanged();

                UpdateCalculatedAmount();
            }
        }

        [XmlIgnore]
        public bool IsAmountCalculated
        {
            get { return isAmountCalculated; }
            set
            {
                isAmountCalculated = value;
                OnPropertyChanged(IsAmountCalculatedPropertyName);
            }
        }

        [XmlAttribute(AttributeName = AmountPropertyName)]
        public decimal Amount
        {
            get { return amount; }
            set
            {
                amount = value;
                OnPropertyChanged(AmountPropertyName);
                
                OnWorksheetItemChanged();

                if (owner != null)
                {
                    owner.UpdateTotalExpense();
                }
            }
        }

        [XmlAttribute(AttributeName = AttachmentsPropertyName)]
        public int Attachments
        {
            get { return attachments; }
            set
            {
                attachments = value;
                OnPropertyChanged(AttachmentsPropertyName);
                
                OnWorksheetItemChanged();
            }
        }

        #endregion

        #region Constructors

        public Expense() { }

        public Expense(ExpenseReport owner)
        {
            this.owner = owner;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Sets the <see cref="ExpenseReport"/> in which the current expense is contained.
        /// </summary>
        /// <param name="owner">The <see cref="ExpenseReport"/> in which the current expense is contained.</param>
        public void SetOwner(ExpenseReport owner)
        {
            this.owner = owner;

            if (owner != null)
            {
                UpdateCalculatedAmount();
            }
        }

        /// <summary>
        /// Updates the <see cref="Amount"/> of the current expense if the <see cref="ExpenseType"/> is
        /// <c>ExpenseType.Fuel</c>.
        /// </summary>
        public void UpdateCalculatedAmount()
        {
            if (owner != null && owner.Owner != null && ExpenseType == ExpenseType.Fuel)
            {
                Amount = (owner.Owner.WorksheetSettings.RefundPerKilometer * Kilometers);
            }
        }

        #endregion
    }
}